package com.ruoyi.ums.service.impl;

import ch.qos.logback.core.util.TimeUtil;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.utils.ApiResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.ums.entity.Member;
import com.ruoyi.ums.mapper.MemberMapper;
import com.ruoyi.ums.service.IMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author kenny
 * @since 2021-11-04
 */
@Slf4j
@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements IMemberService, UserDetailsService {

    @Autowired
    private WxMaService miniApp;
    @Resource
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache redisCache;

    public WxMaJscode2SessionResult registerUser(String code) {
        WxMaJscode2SessionResult result = null;
        try {
            result = miniApp.jsCode2SessionInfo(code);
            QueryWrapper<Member> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(Member::getOpenId, result.getOpenid());
            Member member = baseMapper.selectOne(wrapper);
            if (member == null) {
                member = new Member();
                member.setOpenId(result.getOpenid());
                BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
                member.setUnionId(passwordEncoder.encode(result.getUnionid()));
                baseMapper.insert(member);
            }

//            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(result.getOpenid(), result.getUnionid()));

            redisCache.setCacheObject(Constants.APP_TOKEN_KEY + result.getOpenid(), JSON.toJSONString(member), 15, TimeUnit.DAYS);
        } catch (WxErrorException e) {
            throw new ServiceException(e.getMessage());
        }
        return result;
    }

    public WxMaUserInfo getUserInfo(String sessionKey, String encryptedData, String ivStr) {
        WxMaUserInfo info = miniApp.getUserService().getUserInfo(sessionKey, encryptedData, ivStr);
        Member member = new Member();
        member.setOpenId(info.getOpenId());
        member.setUnionId(info.getUnionId());
        member.setNickname(info.getNickName());
        member.setSex(info.getGender());
        member.setCountry(info.getCountry());
        member.setProvince(info.getProvince());
        member.setCity(info.getCity());
        member.setIntegral(0L);
        member.setCreateTime(DateUtils.getNowDate());
        baseMapper.insert(member);
        return info;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LambdaQueryWrapper<Member> lambda = new QueryWrapper<Member>().lambda();
        lambda.eq(Member::getOpenId, username);
        Member member = baseMapper.selectOne(lambda);
        if (StringUtils.isNull(member)) {
            log.info("登录用户：{} 不存在.", username);
            throw new ServiceException("登录用户：" + username + " 不存在");
        }
        return member;
    }

}
